"""
生成器在调用时才生成元素
"""
# 1可通过列表推导式得到生成器
newlist = [x * 3 for x in range(20)]  # 推导式直接产生整个列表
print(type(newlist))
# 变成生成器generator,用圆括号
g = (x * 3 for x in range(20))
print(type(g))
print(g.__next__())  # 1调用生成器产生元素

# 用系统自带函数next产生，越界会错误
print(next(g))


# 2用函数建立生成器
def func():
    n = 0
    while True:
        n += 1
        yield n  # 只要函数中出现这个关键字yield，函数就变成生成器了。功能：先返回n，然后暂停
    return '越界'  # 当越界错误时，可以用return来显示错误信息


g = func()
print(g)
print(next(g))

print('--------')


# 斐波那契数列生成器
def fib(length):
    a, b = 0, 1
    n = 0

    while n < length:
        print('****', b)
        yield b
        a, b = b, a + b
        n += 1

    return '越界'


g = fib(8)
print(next(g))
print(next(g))
print(next(g))
print(next(g))

print('---------')


#
def gen():
    i = 0
    while i < 5:
        temp = yield i
        print('temp:', temp)
        i += 1
    return '没有更多了'


g = gen()
# print(next(g))
# print(next(g))
# print(next(g))
n = g.send(None)  # 执行到yield暂停，返回i值
print(n)
n1 = g.send('呵呵')  # 从暂停处继续执行，将send给给temp，i给n1
print('n1=', n1)
n2 = g.send('哈哈')
print('n2=', n2)

#处理多任务
def task1(n):
    for i in range(n):
        print('正在搬第{}块砖'.format(i))
        yield None

def task2(n):
    for i in range(n):
        print('正在听第{}首歌'.format(i))
        yield None

g1=task1(10)
g2=task2(5)

while True:
    try:
        g1.__next__()
        g2.__next__()
    except:break
